/**
 * 时间轴拖拽管理器
 * 解决拖拽抖动和状态冲突问题
 */

import { ref, computed, nextTick } from 'vue'

// 拖拽状态类型定义
interface DragState {
  isDragging: boolean
  dragType: 'clip' | 'keyframe' | 'time-indicator' | null
  dragElement: HTMLElement | null
  dragData: any
  startPosition: { x: number; y: number }
  currentPosition: { x: number; y: number }
  offset: { x: number; y: number }
  hasStarted: boolean
  threshold: number
}

// 拖拽配置
interface DragConfig {
  threshold?: number
  timelineZoom: number
  containerElement: HTMLElement | null
  onUpdate?: (data: any) => void
  onComplete?: (data: any) => void
  onCancel?: () => void
}

export function useTimelineDrag() {
  // 拖拽状态
  const dragState = ref<DragState>({
    isDragging: false,
    dragType: null,
    dragElement: null,
    dragData: null,
    startPosition: { x: 0, y: 0 },
    currentPosition: { x: 0, y: 0 },
    offset: { x: 0, y: 0 },
    hasStarted: false,
    threshold: 5
  })

  // 动画帧ID
  const animationFrameId = ref<number | null>(null)

  // 拖拽配置
  const config = ref<DragConfig>({
    threshold: 5,
    timelineZoom: 20,
    containerElement: null
  })

  // 计算属性：是否正在拖拽
  const isDragging = computed(() => dragState.value.isDragging)
  const hasStarted = computed(() => dragState.value.hasStarted)

  /**
   * 开始拖拽片段
   */
  const startClipDrag = (
    clip: any,
    trackId: string,
    element: HTMLElement,
    event: MouseEvent,
    dragConfig: DragConfig
  ) => {
    console.log('🎬 [DragManager] 开始拖拽片段:', {
      clipId: clip.id,
      clipName: clip.name,
      trackId
    })

    // 阻止事件冒泡
    event.stopPropagation()
    event.preventDefault()

    // 获取容器边界
    const containerRect = dragConfig.containerElement?.getBoundingClientRect()
    if (!containerRect) {
      console.error('❌ [DragManager] 无法获取容器边界')
      return
    }

    // 计算鼠标相对于容器的位置
    const mouseX = event.clientX - containerRect.left
    const mouseY = event.clientY - containerRect.top

    // 计算片段在容器中的位置
    const clipRect = element.getBoundingClientRect()
    const clipX = clipRect.left - containerRect.left

    // 计算偏移量（鼠标相对于片段左上角的偏移）
    const offsetX = mouseX - clipX
    const offsetY = mouseY - (clipRect.top - containerRect.top)

    // 设置拖拽状态
    dragState.value = {
      isDragging: true,
      dragType: 'clip',
      dragElement: element,
      dragData: {
        ...clip,
        trackId,
        originalStartTime: clip.startTime,
        originalEndTime: clip.endTime
      },
      startPosition: { x: event.clientX, y: event.clientY },
      currentPosition: { x: event.clientX, y: event.clientY },
      offset: { x: offsetX, y: offsetY },
      hasStarted: false,
      threshold: dragConfig.threshold || 5
    }

    // 保存配置
    config.value = dragConfig

    console.log('📍 [DragManager] 拖拽初始化完成:', {
      mousePosition: { x: mouseX, y: mouseY },
      clipPosition: { x: clipX },
      offset: { x: offsetX, y: offsetY },
      threshold: dragState.value.threshold
    })

    // 添加全局事件监听器
    document.addEventListener('mousemove', handleMouseMove)
    document.addEventListener('mouseup', handleMouseUp)
  }

  /**
   * 处理鼠标移动
   */
  const handleMouseMove = (event: MouseEvent) => {
    if (!dragState.value.isDragging) return

    // 更新当前位置
    dragState.value.currentPosition = { x: event.clientX, y: event.clientY }

    // 计算移动距离
    const deltaX = Math.abs(event.clientX - dragState.value.startPosition.x)
    const deltaY = Math.abs(event.clientY - dragState.value.startPosition.y)
    const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY)

    // 检查是否超过阈值
    if (!dragState.value.hasStarted && distance < dragState.value.threshold) {
      console.log('📏 [DragManager] 移动距离未达到阈值:', { distance, threshold: dragState.value.threshold })
      return
    }

    // 第一次超过阈值，开始真正的拖拽
    if (!dragState.value.hasStarted) {
      console.log('🚀 [DragManager] 开始真正的拖拽')
      dragState.value.hasStarted = true
      
      // 添加拖拽样式
      if (dragState.value.dragElement) {
        dragState.value.dragElement.classList.add('dragging')
        dragState.value.dragElement.style.zIndex = '1000'
      }
    }

    // 取消之前的动画帧
    if (animationFrameId.value) {
      cancelAnimationFrame(animationFrameId.value)
    }

    // 使用 requestAnimationFrame 进行流畅更新
    animationFrameId.value = requestAnimationFrame(() => {
      updateDragPosition(event)
    })
  }

  /**
   * 更新拖拽位置
   */
  const updateDragPosition = (event: MouseEvent) => {
    if (!dragState.value.isDragging || !dragState.value.hasStarted) return

    const containerRect = config.value.containerElement?.getBoundingClientRect()
    if (!containerRect) return

    // 计算鼠标在容器中的位置
    const mouseX = event.clientX - containerRect.left

    // 计算片段新的左侧位置（减去偏移量）
    const newClipX = mouseX - dragState.value.offset.x
    const newStartTime = Math.max(0, newClipX / config.value.timelineZoom)

    // 计算新的结束时间
    const duration = dragState.value.dragData.originalEndTime - dragState.value.dragData.originalStartTime
    const newEndTime = newStartTime + duration

    // 更新拖拽数据
    dragState.value.dragData.startTime = newStartTime
    dragState.value.dragData.endTime = newEndTime

    console.log('🎯 [DragManager] 更新拖拽位置:', {
      mouseX,
      newClipX,
      newStartTime,
      newEndTime,
      duration
    })

    // 使用 transform 更新视觉位置
    if (dragState.value.dragElement) {
      const originalX = dragState.value.dragData.originalStartTime * config.value.timelineZoom
      const translateX = newClipX - originalX
      dragState.value.dragElement.style.transform = `translateX(${translateX}px)`
    }

    // 调用更新回调
    if (config.value.onUpdate) {
      config.value.onUpdate({
        startTime: newStartTime,
        endTime: newEndTime,
        trackId: dragState.value.dragData.trackId,
        clipId: dragState.value.dragData.id
      })
    }
  }

  /**
   * 处理鼠标释放
   */
  const handleMouseUp = () => {
    console.log('🛑 [DragManager] 停止拖拽')

    // 清理动画帧
    if (animationFrameId.value) {
      cancelAnimationFrame(animationFrameId.value)
      animationFrameId.value = null
    }

    // 重置元素样式
    if (dragState.value.dragElement) {
      dragState.value.dragElement.style.transform = ''
      dragState.value.dragElement.style.zIndex = ''
      dragState.value.dragElement.classList.remove('dragging')
    }

    // 如果真正开始了拖拽，调用完成回调
    if (dragState.value.hasStarted && config.value.onComplete) {
      console.log('✅ [DragManager] 提交拖拽结果')
      config.value.onComplete({
        startTime: dragState.value.dragData.startTime,
        endTime: dragState.value.dragData.endTime,
        trackId: dragState.value.dragData.trackId,
        clipId: dragState.value.dragData.id
      })
    } else if (!dragState.value.hasStarted) {
      console.log('ℹ️ [DragManager] 只是点击，未进行拖拽')
    }

    // 重置拖拽状态
    dragState.value = {
      isDragging: false,
      dragType: null,
      dragElement: null,
      dragData: null,
      startPosition: { x: 0, y: 0 },
      currentPosition: { x: 0, y: 0 },
      offset: { x: 0, y: 0 },
      hasStarted: false,
      threshold: 5
    }

    // 移除事件监听器
    document.removeEventListener('mousemove', handleMouseMove)
    document.removeEventListener('mouseup', handleMouseUp)

    console.log('🧹 [DragManager] 拖拽清理完成')
  }

  /**
   * 取消拖拽
   */
  const cancelDrag = () => {
    if (config.value.onCancel) {
      config.value.onCancel()
    }
    handleMouseUp()
  }

  return {
    // 状态
    isDragging,
    hasStarted,
    dragState: computed(() => dragState.value),

    // 方法
    startClipDrag,
    cancelDrag
  }
}
